package cn.xyf.mzmy.common.netty.core.server;

import cn.xyf.mzmy.common.netty.core.handler.TextWebSocketFrameHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class NettyWebSocketServer {


    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private ChannelFuture channelFuture;

    public void start(int port) {
        bossGroup = new NioEventLoopGroup(1);               // 接收连接的线程组
        workerGroup = new NioEventLoopGroup();                       // 处理I/O事件的线程组
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)                 // 使用NIO通道
                    .option(ChannelOption.SO_BACKLOG, 128)           // 设置连接队列大小
                    .childOption(ChannelOption.SO_KEEPALIVE, true)   // 保持连接
                    .handler(new LoggingHandler(LogLevel.INFO))            // 添加日志处理器
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) {
                            ch.pipeline().addLast(
                                    new HttpServerCodec(),      // HTTP 编解码器
                                    new ChunkedWriteHandler(),  // 块写入处理器
                                    new HttpObjectAggregator(65536), // HTTP 对象聚合器
                                    new WebSocketServerProtocolHandler("/ws"), // WebSocket 协议处理器
                                    new TextWebSocketFrameHandler() // 自定义文本帧处理器
                            );
                        }
                    });

            // 绑定端口并同步等待
            channelFuture = b.bind(port).sync();
            log.info("Netty WebSocket Server started on port {}", port);
            // 等待服务器通道关闭
            channelFuture.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            log.error("Error starting Netty server", e);
            Thread.currentThread().interrupt(); // 保留中断状态
        } finally {
            stop(); // 确保资源被释放
        }
    }

    public void stop() {
        log.info("Shutting down Netty WebSocket Server...");
        if (channelFuture != null) {
            channelFuture.channel().close(); // 关闭服务器通道
        }
        if (workerGroup != null) {
            workerGroup.shutdownGracefully(); // 优雅关闭工作线程组
        }
        if (bossGroup != null) {
            bossGroup.shutdownGracefully(); // 优雅关闭Boss线程组
        }
        log.info("Netty WebSocket Server stopped.");
    }
}